/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.web.Util;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.mapper.CorpManagementMapper;
import com.koron.scene.domain.Enterprise;
import com.koron.scene.domain.Project;
import com.koron.scene.domain.ProjectEnterprise;
import com.koron.scene.mapper.EnterpriseMapper;
import com.koron.scene.mapper.ProjectAssessmentMapper;
import com.koron.scene.mapper.ProjectEnterpriseMapper;
import com.koron.scene.mapper.ProjectMapper;
import com.koron.scene.service.api.EnterpriseService;
import com.koron.scene.utils.BaseEntityUtil;
import com.koron.scene.utils.BusinessCode;
import com.koron.scene.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.koron.scene.service.impl.DeviceServiceImpl.checkObjAllFieldsIsNull;
import static com.koron.scene.utils.ExcelUtil.getCellValue;

@Service
public class EnterpriseServiceImpl implements EnterpriseService {

    @Autowired
    private Util util;

    private static final Logger logger = LoggerFactory.getLogger(EnterpriseServiceImpl.class);

    MessageBean<Enterprise> buildEnterprise(String name, String enterpriseType, Double registerCapital, String address,
                                            String businessScope, String legalPerson, String establishDateStr,
                                            String phoneNumber, String corpCode) {
        MessageBean<Enterprise> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Enterprise.class);
        if (StringUtils.isBlank(name)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        if (StringUtils.isBlank(enterpriseType)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        if (registerCapital != null && registerCapital < 0) {
            msg.setCode(29001);
            msg.setDescription("注册资金异常");
            return msg;
        }
        Enterprise enterprise = new Enterprise();
        enterprise.setName(name);
        enterprise.setEnterpriseType(enterpriseType);
        enterprise.setRegisterCapital(registerCapital);
        enterprise.setAddress(address);
        enterprise.setBusinessScope(businessScope);
        enterprise.setLegalPerson(legalPerson);
        enterprise.setEstablishDate(DateUtil.formatStringToDate(establishDateStr, DateUtil.DATE_FORMAT_YMD));
        enterprise.setPhoneNumber(phoneNumber);
        enterprise.setCorpCode(corpCode);
        msg.setData(enterprise);
        return msg;
    }

    @Override
    public MessageBean<?> add(String name, String enterpriseType, Double registerCapital, String address,
                              String businessScope, String legalPerson, String establishDateStr, String phoneNumber,
                              String corpCode, StaffBean user) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        MessageBean<Enterprise> messageBean = buildEnterprise(name, enterpriseType, registerCapital, address, businessScope,
                legalPerson, establishDateStr, phoneNumber, corpCode);
        if (messageBean.getCode() != 0) {
            return messageBean;
        }
        Enterprise enterprise = messageBean.getData();
        SessionFactory factory = new SessionFactory();
        try {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            //名称校验
            List<Enterprise> list = mapper.selectByName(name);
            if (list != null && list.size() > 0) {
                msg.setCode(BusinessCode.SAME_ENTERPRISE_NAME.getCode());
                msg.setDescription(BusinessCode.SAME_ENTERPRISE_NAME.getDescription());
                return msg;
            }
            BaseEntityUtil.setAddBaseProperties(enterprise, user);
            mapper.insert(enterprise);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            factory.close(false);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> update(String enterpriseId, String name, String enterpriseType, Double registerCapital, String address, String businessScope, String legalPerson, String establishDateStr, String phoneNumber, String corpCode, StaffBean user) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        MessageBean<Enterprise> messageBean = buildEnterprise(name, enterpriseType, registerCapital, address, businessScope,
                legalPerson, establishDateStr, phoneNumber, corpCode);
        if (messageBean.getCode() != 0) {
            return messageBean;
        }
        if (StringUtils.isBlank(enterpriseId)) {
            msg.setCode(BusinessCode.INSUFFICIENT_PARAM.getCode());
            msg.setDescription(BusinessCode.INSUFFICIENT_PARAM.getDescription());
            return msg;
        }
        Enterprise enterprise = messageBean.getData();
        enterprise.setId(enterpriseId);
        SessionFactory factory = new SessionFactory();
        try {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);

            //名称校验
            List<Enterprise> list = mapper.selectByName(name);
            if (list != null && list.size() > 0) {
                List<Enterprise> sameList = list.stream().filter(l -> {
                    return !enterpriseId.equals(l.getId()) && name.equals(l.getName());
                }).collect(Collectors.toList());
                if (sameList != null && sameList.size() > 0) {
                    msg.setCode(BusinessCode.SAME_ENTERPRISE_NAME.getCode());
                    msg.setDescription(BusinessCode.SAME_ENTERPRISE_NAME.getDescription());
                    return msg;
                }
            }
            BaseEntityUtil.setUpdateBaseProperties(enterprise, user);
            mapper.updateByPrimaryKeySelective(enterprise);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    void setProperties(List<Enterprise> list, ProjectMapper projectMapper, ProjectAssessmentMapper assessmentMapper) {
        for (Enterprise enterprise : list) {
            if (enterprise != null) {
                List<Project> projectList = projectMapper.queryListByEnterpriseId(enterprise.getId());
                enterprise.setProjectList(projectList);
                enterprise.setTotalProject(projectList == null ? 0 : projectList.size());
                Double score = assessmentMapper.getAssessmentScoreByEnterpriseId(enterprise.getId());
                enterprise.setScore(score);
            }
        }
    }

    @Override
    public MessageBean<?> list(StaffBean user, String name, String enterpriseType, String corpCode,String keyword, Integer page, Integer pageSize) {
        MessageBean<DataBean> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), DataBean.class);
        try (SessionFactory factory = new SessionFactory()) {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            ProjectMapper projectMapper = factory.getMapper(ProjectMapper.class);
            ProjectAssessmentMapper assessmentMapper = factory.getMapper(ProjectAssessmentMapper.class);
            Integer start = null;
            if (page != null && pageSize != null && page > 0 && pageSize > 0) {
                start = (page - 1) * pageSize;
            }
            // 获取单位及其下属所有的子单位
            String codes = util.getDeptCodes(corpCode);
            List<Enterprise> list = mapper.queryListByCondition(name, enterpriseType, codes, start, pageSize,keyword);
            list.forEach(bean->{
                if (StringUtils.isNotEmpty(bean.getCorpCode())){
                    CorpBean corpBean = factory.getMapper(CorpManagementMapper.class).get(bean.getCorpCode());
                    bean.setCorpName(corpBean == null ? null : corpBean.getCorpName());
                }
            });
            int total = mapper.countList(name, enterpriseType, codes,keyword);
            //需处理 项目相关的属性
            if (list != null && list.size() > 0) {
                setProperties(list, projectMapper, assessmentMapper);
            }
            DataBean dataBean = new DataBean();
            dataBean.setTotalPage(start == null ? 0 : total / pageSize);
            dataBean.setTotalNumber(total);
            dataBean.setPageNo(page);
            dataBean.setPageSize(pageSize);
            dataBean.setList(list);
            msg.setData(dataBean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<?> selectList(StaffBean user, String name,String corpCode) {
        MessageBean<List> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), List.class);
        try (SessionFactory factory = new SessionFactory()) {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            List<Enterprise> list = mapper.queryList(name, null, corpCode, null, null);
            msg.setData(list);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
        }
        return msg;
    }

    @Override
    public MessageBean<?> delete(StaffBean user, String enterpriseId) {
        MessageBean<?> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Object.class);
        SessionFactory factory = new SessionFactory();
        try {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            ProjectEnterpriseMapper projectEnterpriseMapper = factory.getMapper(ProjectEnterpriseMapper.class);
            //判断是否存在关联,是否可以删除
            List<ProjectEnterprise> list = projectEnterpriseMapper.selectByEnterpriseId(enterpriseId);
            if (list != null && !list.isEmpty()) {
                msg.setCode(BusinessCode.ENTERPRISE_EXIST_PROJECT.getCode());
                msg.setDescription(BusinessCode.ENTERPRISE_EXIST_PROJECT.getDescription());
                return msg;
            }
            //需删除相关项目信息；
            projectEnterpriseMapper.deleteByEnterpriseId(enterpriseId);
            mapper.deleteByPrimaryKey(enterpriseId);

        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @Override
    public MessageBean<?> importExcel(StaffBean user, MultipartFile file) {
        MessageBean<String> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), "导入成功", String.class);
        SessionFactory factory = new SessionFactory();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<Enterprise> list = new ArrayList<>();
        List<Enterprise> enterprisesList = new ArrayList<>();
        try {
            InputStream inputStream = file.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                msg.setDescription(BusinessCode.FAILURE.getDescription());
                msg.setCode(BusinessCode.FAILURE.getCode());
                return msg;
            }
            // 获取excel表格行数
            int rows = sheet.getPhysicalNumberOfRows();
            // 从第二行开始读取数据
            for (int i = 2; i < rows; i++) {
                Enterprise enterprise = new Enterprise();
                XSSFRow row = sheet.getRow(i);
                String name = getCellValue(row.getCell(0));
                String enterpriseType = getCellValue(row.getCell(1));
                String registerCapital = getCellValue(row.getCell(2));
                String address = getCellValue(row.getCell(3));
                String businessScope = getCellValue(row.getCell(4));
                String legalPerson = getCellValue(row.getCell(5));
                String establishDate = getCellValue(row.getCell(6));
                String phoneNumber = getCellValue(row.getCell(7));
                if (!StringUtils.isEmpty(name)) {
                    enterprise.setName(name);
                }
                if (!StringUtils.isEmpty(enterpriseType)) {
                    enterprise.setEnterpriseType(("施工方").equals(enterpriseType) ? "0" : ("监理方").equals(enterpriseType) ? "1" : null);
                }
                if (!StringUtils.isEmpty(registerCapital)) {
                    enterprise.setRegisterCapital(Double.valueOf(registerCapital));
                }
                if (!StringUtils.isEmpty(address)) {
                    enterprise.setAddress(address);
                }
                if (!StringUtils.isEmpty(businessScope)) {
                    enterprise.setBusinessScope(businessScope);
                }
                if (!StringUtils.isEmpty(legalPerson)) {
                    enterprise.setLegalPerson(legalPerson);
                }
                if (!StringUtils.isEmpty(establishDate)) {
                    Date date = null;
                    try {
                        // 如果excel中为文本格式，切符合yyyy-MM-dd，直接转换成Date类型
                        date = sdf.parse(establishDate);
                    } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                    } finally {
                        if (null == date) {
                            // 转换失败，默认excel中为日期格式
                            date = HSSFDateUtil.getJavaDate(Double.parseDouble(establishDate));
                        }
                    }
                    if (null != date) {
                        enterprise.setEstablishDate(date);
                    }
                }
                if (!StringUtils.isEmpty(phoneNumber)) {
                    enterprise.setPhoneNumber(phoneNumber);
                }
                if (!checkObjAllFieldsIsNull(enterprise)) {
                    list.add(enterprise);
                }
            }
            if (list.size() > 0) {
                // 获取用户所在公司
                String corpCode = null;
                MessageBean<?> corpMsg = util.corp(user.getCode());
                if (corpMsg.getCode() == 0 && null != corpMsg.getData()) {
                    DepartmentTreeBean corp = (DepartmentTreeBean) corpMsg.getData();
                    corpCode = corp.getDepartmentCode();
                }
                for (Enterprise bean : list) {
                    bean.setId(DefaultIdGenerator.getInstance().generateLongId());
                    bean.setAddUser(user.getCode());
                    bean.setAddUserName(user.getName());
                    bean.setAddTime(new Date());
                    bean.setCorpCode(corpCode);
                }
                Integer integer = factory.getMapper(EnterpriseMapper.class).batchInsert(list);
                if (integer <= 0) {
                    factory.close(false);
                    msg.setCode(BusinessCode.FAILURE.getCode());
                    msg.setDescription(BusinessCode.FAILURE.getDescription());
                    return msg;
                }
            }
            factory.close();
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            if (null != factory) {
                factory.close(false);
            }
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription("导入失败");
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    @Override
    public List<Enterprise> exportList(StaffBean user, String corpCode, String name, String enterpriseType) {
        try (SessionFactory factory = new SessionFactory()) {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            ProjectMapper projectMapper = factory.getMapper(ProjectMapper.class);
            ProjectAssessmentMapper assessmentMapper = factory.getMapper(ProjectAssessmentMapper.class);
            String codes = util.getDeptCodes(corpCode);
            List<Enterprise> list = mapper.queryListByCondition(name, enterpriseType, codes, null, null,null);
            //需处理 项目相关的属性
            if (list != null && list.size() > 0) {
                setProperties(list, projectMapper, assessmentMapper);
                list.forEach(bean -> {
                    if (StringUtils.isNotEmpty(bean.getCorpCode())) {
                        List<DepartmentTreeBean> departmentTreeBeanList = (List<DepartmentTreeBean>) util.depttree(bean.getCorpCode(), 0).getData();
                        Map<String, String> map = departmentTreeBeanList.stream().collect(Collectors.toMap(DepartmentTreeBean::getDepartmentCode, DepartmentTreeBean::getName));
                        bean.setCorpName((departmentTreeBeanList == null || departmentTreeBeanList.size() <= 0)
                                ? null : map.get(bean.getCorpCode()));
                    }
                    if (StringUtils.isNotEmpty(bean.getEnterpriseType())) {
                        if ("0".equals(bean.getEnterpriseType())) {
                            bean.setEnterpriseType("施工方");
                        } else if ("1".equals(bean.getEnterpriseType())) {
                            bean.setEnterpriseType("监理方");
                        }
                    }
                });
            }
            return list;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return null;
        }
    }

    @Override
    public MessageBean<?> details(StaffBean user, String enterpriseId) {
        MessageBean<Enterprise> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), Enterprise.class);
        SessionFactory factory = new SessionFactory();
        try {
            EnterpriseMapper mapper = factory.getMapper(EnterpriseMapper.class);
            ProjectMapper projectMapper = factory.getMapper(ProjectMapper.class);
            ProjectAssessmentMapper assessmentMapper = factory.getMapper(ProjectAssessmentMapper.class);
            //判断是否存在关联,是否可以删除
            Enterprise enterprise = mapper.queryOne(enterpriseId);
            if (enterprise != null) {
                List<Project> projectList = projectMapper.queryListByEnterpriseId(enterprise.getId());
                enterprise.setProjectList(projectList);
                enterprise.setTotalProject(projectList == null ? 0 : projectList.size());
                Double score = assessmentMapper.getAssessmentScoreByEnterpriseId(enterprise.getId());
                enterprise.setScore(score);
            }
            msg.setData(enterprise);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.FAILURE.getCode());
            msg.setDescription(BusinessCode.FAILURE.getDescription());
            factory.close(false);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }
}
